package com.runshu.newsmartark.base;

import android.annotation.SuppressLint;
import android.app.ZysjSystemManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.alibaba.fastjson.JSON;
import com.rscja.utility.StringUtility;
import com.runshu.newsmartark.R;
import com.runshu.newsmartark.activity.NewMainactivity;
import com.runshu.newsmartark.activity.RegisterAndRecognizeActivity;
import com.runshu.newsmartark.common.CMD;
import com.runshu.newsmartark.common.ConstantUrl;
import com.runshu.newsmartark.entity.UserInfoEntity;
import com.runshu.newsmartark.event.Event;
import com.runshu.newsmartark.event.EventBusUtils;
import com.runshu.newsmartark.event.EventCode;
import com.runshu.newsmartark.smartbox.SmartBoxHelper;
import com.runshu.newsmartark.smartbox.SmartBoxListener;
import com.runshu.newsmartark.smartbox.TarGet;
import com.runshu.newsmartark.util.FinishActivityManager;
import com.runshu.newsmartark.util.SoundPoolUtils;
import com.runshu.newsmartark.util.common.SharedPreferencesUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Timer;

import cn.com.example.rfid.driver.Driver;
import cn.com.example.rfid.driver.RfidDriver;

import static com.runshu.newsmartark.common.ConstantUrl.REMOTE_OPEN;
import static com.runshu.newsmartark.util.MQTTManager.PUB_TOPIC;
import static java.lang.Thread.sleep;

public abstract class BoxBaseActivity extends BaseActivity {
    private LocalBroadcastManager lbm;
    public static List<SmartBoxListener> listeners = new ArrayList<>();
    public static BoxBaseActivity ctx;
    Handler handler;
    Handler stopHandler;
    int iIndex = 0;
    long curDate, lastData;
    private boolean isClose = false;

    long startADate, startBDate;
    long lastADate, lastBDate;
    int Ct = 0;
    int flag = 0;
    public static String mStopTime = "10";
    public static boolean isStopTime = false;
    private int g_CloseDoorFlag = 0x0010;   // 默认电插锁0x0000，关门后GPIO5检测高电平  0x0010 电吸锁
    Timer soundTimer = new Timer();
    private ArrayList<HashMap<String, String>> tagList = new ArrayList<HashMap<String, String>>();
    private Map<String, HashMap<String, String>> tagresult = new HashMap<>();

    HashMap<String, String> hmap = new HashMap<>();
    HashMap<String, Integer> map = new HashMap<String, Integer>(100000);
    Driver driver;
    private boolean loopFlag = false;
    private static LocalBroadcastManager mLocalBroadcastManager = null;
    //引入Android工控板gpio，进行开关门的控制以及红外感应控制
    ZysjSystemManager mManager = null;
    private boolean mIsRunning = true;
    private static final int HANDLER_GET_ALL_VALUE = 2;
    int gpio3Value;
    int gpio4Value;
    private static boolean isFace = true;

    public void addBoxListener(SmartBoxListener listener) {
        Log.e("box", "addboxlistener");
        listeners.add(listener);
    }

    public void unRegisterBoxListener(SmartBoxListener listener) {
        Log.e("box", "unregisterboxlistener");
        listeners.remove(listener);
    }

    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 2: {
                    new Thread(new Runnable() {

                        @Override
                        public void run() {
                            getAllGpioValue();
                        }
                    }).start();
                }
                break;
                case 100: {
                    if ("activity.NewMainactivity".equals(FinishActivityManager.getManager().currentActivity().getLocalClassName())) {
                        if (0 == gpio4Value && isFace){ //靠近
                            Intent intent = new Intent();
                            SoundPoolUtils.play(context, R.raw.raw_face, 0);
                            intent.setClass(context, RegisterAndRecognizeActivity.class);
                            startActivity(intent);
                            isFace = false;
                        }
                    }
                    if (1 == gpio4Value){//远离
                        FinishActivityManager.getManager().finishActivity(RegisterAndRecognizeActivity.class);
                        isFace = true;
                    }
//                    if (1 == gpio4Value) {        //远离
//
//
//                    } else if (0 == gpio4Value) {  //靠近
//                        Intent intent = new Intent();
//                        SoundPoolUtils.play(context, R.raw.raw_face, 0);
//                        intent.setClass(context, RegisterAndRecognizeActivity.class);
//                        startActivity(intent);
//
//                    }
                    if (isClose) {
                        if (1 == gpio3Value) {        //防止钩锁烧毁
                            Log.e("Close", "1的时候关门");
                            mManager.set_zysj_gpio_value(1, 1);
                            //发送关门
                            sendBroadMessage(CMD.CloseDoorBroadcast);
                            SoundPoolUtils.play(context, R.raw.raw_close, 0);
                            isClose = false;
                        }
                    }
                }
                break;
            }

        }
    };


    //查询gpio状态
    //查询电钩锁状态
    /*
                Gpio3       输入   1      开门
                                  0      关门
     */
    //查询红外感应状态
    /*
                    Gpio4       输入   1      远离
                                      0      靠近
     */
    private void getAllGpioValue() {
        if (isClose) {
            gpio3Value = mManager.get_zysj_gpio_value(3);
            Log.e("Gpio", "3 value = " + gpio3Value);
        }
        gpio4Value = mManager.get_zysj_gpio_value(4);
        mHandler.sendEmptyMessage(100);
    }

    class ReadGpioDataThread extends Thread {

        @Override
        public void run() {
            super.run();
            while (mIsRunning) {
                try {
                    Thread.sleep(100);
                    mHandler.sendEmptyMessage(HANDLER_GET_ALL_VALUE);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @SuppressLint("WrongConstant")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ctx = this;
        mLocalBroadcastManager = LocalBroadcastManager.getInstance(ctx);
        lbm = LocalBroadcastManager.getInstance(this);

        IntentFilter itent = new IntentFilter();
        itent.addAction(CMD.CloseDoorBroadcast);
        itent.addAction(CMD.OpenDoorBroadcast);
        itent.addAction(CMD.InventoryBroadcast);
        lbm.registerReceiver(receiver, itent);
        driver = new RfidDriver();

        handler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                addEPCToList(msg.obj + "", hmap, tagList);
                long nowTime = System.currentTimeMillis();
                long timedate = nowTime - lastData;
                Ct++;
            }
        };


        stopHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (msg.obj == "start") {

                    if (TarGet.getCurrentTarget() == 0) {
                        lastADate = System.currentTimeMillis() - startADate;
                        //todo targetresult 添加targetlist
                        for (HashMap<String, String> tmp : tagList) {
                            tagresult.put(tmp.get("epc"), tmp);
                        }
                        TarGet.setCurrentTarget(1);
                        Log.e("box_ab_scan==", "A面数据==" + tagList.size() + "res:" + tagresult.keySet().size());
                        SmartBoxHelper.getInstance().startScanA(context, 0);

                    } else {
                        //停止
                        for (HashMap<String, String> tmp : tagList) {
                            tagresult.put(tmp.get("epc"), tmp);
                        }
                        onScanResult(new ArrayList<>(tagresult.values()), lastADate, lastBDate);
                        Log.e("box_ab_scan==", "最后数据==" + tagList.size() + "res:" + tagresult.keySet().size());
                        Log.d("action", "停止");
                        tagList.clear();
                        TarGet.setCurrentTarget(0);
                    }

                }
            }
        };


        //Android工控板gpio
        mManager = (ZysjSystemManager) getApplicationContext().getSystemService("zysj");
        (new ReadGpioDataThread()).start();

    }

    public boolean isCloseDoor() {
//        gpio3状态，  查询到1是关门状态，0是开门状态
        gpio3Value = mManager.get_zysj_gpio_value(3);
        return gpio3Value == 1;

    }

    public void onScanResult(List<HashMap<String, String>> data, long a, long b) {
        Log.w("operatebox---", "scan");
        SmartBoxHelper.getInstance().stopScan(this);
        if (listeners != null) {
            for (SmartBoxListener smartBoxListener : listeners) {
                smartBoxListener.onScanResult(data, isCloseDoor(), a, b);
            }
        }
    }


    private void onOpenDoor() {
        Log.w("operatebox---", "opendoor");
        if (listeners != null) {
//            isCloseDoor = true;
            for (SmartBoxListener smartBoxListener : listeners) {
                smartBoxListener.onOpenDoor();
            }
        }
    }

    private void onCloseDoor() {


        Log.w("box", "app_oncloseDoor");
        SmartBoxHelper.getInstance().closeLigth(this, 0);
        Log.w("box", "app_listener" + listeners == null ? "null" : listeners.size() + "");

        if (listeners != null) {
            for (SmartBoxListener smartBoxListener : listeners) {
                smartBoxListener.onCloseDoor();
            }
        }
    }

    // 设置检测关门方式   sw == 0 低电平关门，对应电插锁； sw == 1 高电平关门，对应电磁锁
    public boolean SetCloseDoorMode(int sw) {
        if (sw == 1) {
            g_CloseDoorFlag = 0x0010;
        } else {
            g_CloseDoorFlag = 0x0000;
        }

        return true;
    }

    // sw = 0，开门；
    public boolean SetDoorStatus(int sw) {
        if (0 == sw) {
            mManager.set_zysj_gpio_value(1, sw);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(800);
                        mManager.set_zysj_gpio_value(1, 1);
                        Log.e("执行", "关门");
                        isClose = true;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
//            new Handler().postDelayed(new Runnable() {
//                @Override
//                public void run() {
//                    mManager.set_zysj_gpio_value(1, 1);
//                    Log.e("执行", "关门");
//                    isClose = true;
//                }
//            }, 800);
        }

        return true;

    }
    // sw = 1，开门；       sw = 0，关门
//    public boolean SetNotActionDoorStatus(int sw) {
//        int mask = 0x0100;
//        int value = (int) (sw << 8);
//        int save = 0;
//        // 判断是否开启监听
//        if (loopFlag)
//        {
//            loopFlag    = false;
//            try {
//                sleep(200);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
//        int result = driver.SetGPIOStatus(mask, value, save);
//        return result == 1;
//    }

//    // sw = 1，开灯；       sw = 0，关灯
//    public boolean SetLightStatus(int sw) {
//        int mask = 0x0200;
//        int value = (int) (sw << 9);
//        int save = 0;
//        // 判断是否开启监听
//        if (loopFlag)
//        {
//            loopFlag    = false;
//            try {
//                sleep(200);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
//        int result = driver.SetGPIOStatus(mask, value, save);
//        if (result == 1) {
//            return true;
//        } else {
//            return false;
//        }
//    }

    //    // 开启监听关门事件   sw == 1 开启； sw == 0 关闭；
//    public boolean ListenDoorCloseEvent(int sw) {
//        if (sw == 1) {
//            new GPIOThread().start();
//            loopFlag = true;
//        } else {
//            loopFlag = false;
//        }
//
//        return true;
//    }
    // 设置读写器发射功率
    public boolean SetReaderTxPower(int rPow, int wPow, int ant) {
        // antID 天线号，=0，表示
        int readPow, writePow, antID, saveFlag;

        readPow = rPow;             // readPow 读功率
        writePow = wPow;             // writePow 写功率
        antID = ant;              // antID 天线号，antID=0，表示设置所有天线的发射功率
        saveFlag = 1;                // 1 设置掉电保存，    0 设置掉电不保存，重启模块后，需重新设置
        int result = driver.SetTxPower(readPow, writePow, antID, saveFlag);
        if (result == 1) {
            return true;
        } else {
            return false;
        }
    }

    // 检测读写器端口和天线是否正常连接
    public String[] CheckReaderPortStatus() {
        String result = driver.Get_AntStatus();

        if ((result.equals("-1000")) || (result.equals("-1020"))) {
            return null;
        } else {
            String[] AntArrary = result.split(",");

            return AntArrary;
        }
    }

    // 设置读写器天线  antNum表示要设置的天线数量，
    // 举例, 设置天线1-天线8，共8个天线工作，则ant[] = {1, 2, 3, 4, 5, 6, 7, 8}, antNum = 8
    public boolean SetReaderAntenna(int[] ant, int antNum) {
        int saveFlag;

        saveFlag = 1;                // 1 设置掉电保存，    0 设置掉电不保存，重启模块后，需重新设置
        int result = driver.Set_Ant_More(ant, antNum, saveFlag);
        if (result == 1) {
            return true;
        } else {
            return false;
        }
    }
//    class GPIOThread extends Thread {
//
//        private int mBetween = 100;
//
//        public GPIOThread() {
//
//        }
//
//        public void run() {
//
//            while (loopFlag) {
//
//                try {
//                    int result = driver.GetGPIOStatus((byte) 0x10);
//                    if ((result & 0x0010) == g_CloseDoorFlag) {
//                        sendBroadMessage(CMD.CloseDoorBroadcast);
//                        loopFlag = false;
//                    }
//
//                    sleep(mBetween);
//
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.e("Receive", "Enter here");
            String action = intent.getAction();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                switch (Objects.requireNonNull(action)) {
                    case CMD.CloseDoorBroadcast:
//                        关灯
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                startInventory();
                            }
                        }, 100);
//                        onCloseDoor();
                        EventBusUtils.sendEvent(new Event(EventCode.EventClose));
                        break;
                    default:
                        break;
                }
            }
        }
    };


    class TagThread extends Thread {

        private int mBetween = 0;

        public TagThread() {

        }

        public void run() {

            while (loopFlag) {

                if (isStopTime == true) {
                    curDate = System.currentTimeMillis();
                    long diff = curDate - lastData;

                    if ((mStopTime == null) || mStopTime.isEmpty()) {
                        mStopTime = "0";
                    }

                    int stopTime = Integer.parseInt(mStopTime);
                    if (diff > (stopTime)) {
//                        stopInventory();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        flag = 0;

                        Message msg = stopHandler.obtainMessage();

                        msg.obj = "start";
                        stopHandler.sendMessage(msg);

                        break;
                    }
                }

                try {
                    String[] strEpc1 = {driver.GetBufData()};
                    String strEpc = strEpc1[0];
                    if (!StringUtility.isEmpty(strEpc)) {

                        if (strEpc.equals("Finish")) {

//                            // 盘点完成自动结束
//                            driver.stopRead();

                            flag = 0;
                            Message msg = stopHandler.obtainMessage();
                            msg.obj = "start";
                            stopHandler.sendMessage(msg);

                            break;
                        }

                        Message msg = handler.obtainMessage();

                        msg.obj = strEpc;
                        handler.sendMessage(msg);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                try {
                    sleep(mBetween);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    public static int hexStringToAlgorism(String hex) {
        hex = hex.toUpperCase();
        int max = hex.length();
        int result = 0;
        for (int i = max; i > 0; i--) {
            char c = hex.charAt(i - 1);
            int algorism = 0;
            if (c >= '0' && c <= '9') {
                algorism = c - '0';
            } else {
                algorism = c - 55;
            }
            result += Math.pow(16, max - i) * algorism;
        }
        return result;
    }

    private void addEPCToList(String epc, HashMap<String, String> hmap, ArrayList<HashMap<String, String>> tagList) {

        int Hb = 0;
        int Lb = 0;
        int rssi = 0;
        String[] tmp = new String[3];
        HashMap<String, String> temp = new HashMap<>();
        String text = epc.substring(4);
        String len = epc.substring(0, 2);
        int epclen = (Integer.parseInt(len, 16) / 8) * 4;
        tmp[0] = text.substring(epclen, text.length() - 6);
        tmp[1] = text.substring(0, text.length() - 6);
        tmp[2] = text.substring(text.length() - 6, text.length() - 2);

        if (4 != tmp[2].length()) {
            tmp[2] = "0000";
        } else {
            Hb = Integer.parseInt(tmp[2].substring(0, 2), 16);
            Lb = Integer.parseInt(tmp[2].substring(2, 4), 16);
            rssi = ((Hb - 256 + 1) * 256 + (Lb - 256)) / 10;
        }

        int count = 0;

        if (tmp[1].length() <= 30) {
            temp.put("epc", tmp[1]);


            if (hmap.containsKey(tmp[1])) {
                String strTemp = hmap.get(tmp[1]);
                if (null != strTemp) {
                    int sn = Integer.valueOf(strTemp.split(",")[1]);
                    count = Integer.valueOf(strTemp.split(",")[0]) + 1;
                    temp.put("sn", "" + sn);
                    temp.put("count", "" + count);
                    temp.put("rssi", "" + rssi);
                    hmap.put(tmp[1], String.valueOf(count) + "," + String.valueOf(sn) + "," + rssi);
                    tagList.set(sn, temp);
                }
            } else {
                hmap.put(tmp[1], "1," + iIndex + "," + rssi);
                temp.put("sn", "" + iIndex);
                temp.put("count", "1");
                temp.put("rssi", "" + rssi);
                tagList.add(temp);
                //mListView.setAdapter(adapter);
                iIndex++;
            }
        }
    }

//    /**
//     * 停止识别
//     */
//    public void stopInventory() {
//
//        if (loopFlag) {
//
//            loopFlag = false;
//
//            driver.stopRead();
//
//        }
//
//    }

    /**
     * 开始识别
     */
    public void startInventory() {
        switch (flag) {
            case 0:
                tagList.clear();
                map.clear();
                hmap.clear();
                iIndex = 0;
                Ct = 0;
                // 设置Session和Target
                int session = 2;
                int times;
//                if (TarGet.getCurrentTarget() == 0) {
//                     times = (int) SharedPreferencesUtils.get( MyApplication.getApplication(), ConstantUrl.Share_CycleANum, 4 );
//                    startADate = System.currentTimeMillis();
//                    sendBroadMessage(CMD.InventoryBroadcast);
//                    Log.e("box_ab_scan", "开始盘点A ;A循环次数："+times);
//                } else {
//                    tagresult.clear();
//                    times = (int) SharedPreferencesUtils.get( MyApplication.getApplication(), ConstantUrl.Share_CycleBNum, 1 );
//                    startBDate = System.currentTimeMillis();
//                    Log.e("box_ab_scan", "开始盘点B ; B循环次数："+times);
//                }
                if (TarGet.getCurrentTarget() == 0) {
                    tagresult.clear();
                    times = (int) SharedPreferencesUtils.get(MyApplication.getApplication(), ConstantUrl.Share_CycleANum, 2);
                    startADate = System.currentTimeMillis();
                    Log.e("box_ab_scan", "开始盘点A ;A循环次数：" + times);
                } else {
                    times = (int) SharedPreferencesUtils.get(MyApplication.getApplication(), ConstantUrl.Share_CycleBNum, 2);
                    startBDate = System.currentTimeMillis();
                    sendBroadMessage(CMD.InventoryBroadcast);
                    Log.e("box_ab_scan", "开始盘点B ; B循环次数：" + times);
                }
                int target = TarGet.getCurrentTarget();
                SetReaderSession(session, target);
                driver.readMore(times);
                loopFlag = true;
                new TagThread().start();
                lastData = System.currentTimeMillis();

                if (soundTimer == null) {
                    soundTimer = new Timer();
                }
                flag = 1;
                break;
            case 1:
                iIndex = 0;
//                stopInventory();
//                try {
//                    Thread.sleep(5);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                flag = 0;
                break;
            default:
                break;
        }


    }

    // 设置Session和 A/B     {A: target = 0}  {B: target = 1}
    public boolean SetReaderSession(int session, int target) {
        Log.e("box_setting", session + ":s|t:" + target);
        int[] gen2 = new int[10];

        // 先获取，才能设置
        String val = driver.GetGen2Para();

        if ((val.equals("-1000")) || (val.equals("-1020"))) {
            return false;
        }

        for (int i = 0; i < 8; i++) {
            // 获取参数
            gen2[i] = Integer.parseInt(val.substring(2 * i, 2 * (i + 1)), 16);
        }

        // 修改session
        gen2[3] = gen2[3] & 0xCF;
        int pos = session;
        gen2[3] = gen2[3] + (pos << 4);

        // 修改Target
        gen2[3] = gen2[3] & 0xF7;
        pos = target;
        gen2[3] = gen2[3] + (pos << 3);

        int status = 0;
        status = driver.SetGen2Para(0, gen2);            // 不掉电保存参数
        if (1 == status) {
            return true;
        } else {
            return false;
        }
    }

    //  发送广播
    public void sendBroadMessage(String msg) {
        Intent intent = new Intent();
        intent.setAction(msg);
        mLocalBroadcastManager.sendBroadcast(intent);
    }
}
